package cn.chiship.sdk.core.util.http;

import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.core.enums.ContentTypeEnum;
import cn.chiship.sdk.core.enums.FileExtEnum;
import cn.chiship.sdk.core.enums.HeaderEnum;
import cn.chiship.sdk.core.text.CharsetKit;
import com.alibaba.fastjson.JSON;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * response工具类
 *
 * @author lijian
 */
public class ResponseUtil {

	public void download(HttpServletResponse response, FileExtEnum fileExtEnum, String fileName, byte[] bytes)
			throws Exception {
		switch (fileExtEnum.getName()) {
		case BaseConstants.EXPORT_FORMAT_XLS:
			xls(fileName, bytes, response);
			break;
		case BaseConstants.EXPORT_FORMAT_XLSX:
			xlsx(fileName, bytes, response);
			break;
		case BaseConstants.EXPORT_FORMAT_CSV:
			csv(fileName, bytes, response);
			break;
		case BaseConstants.EXPORT_FORMAT_JSON:
			json(fileName, bytes, response);
			break;
		case BaseConstants.EXPORT_FORMAT_TXT:
			text(fileName, bytes, response);
			break;
		default:
			stream(fileName, bytes, response);
		}
	}

	/**
	 * 统一输出JSON接口
	 * @param response 响应
	 * @param baseResult 结果
	 * @throws IOException 异常
	 */
	public static void writeJson(HttpServletResponse response, BaseResult baseResult) throws IOException {
		writeJson(response, JSON.toJSONString(baseResult));
	}

	/**
	 * 统一输出JSON接口
	 * @param response 响应
	 * @param value 结果
	 * @throws IOException 异常
	 */
	public static void writeJson(HttpServletResponse response, String value) throws IOException {
		response.setContentType("application/json;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.write(value);
		out.flush();
		out.close();
	}

	/**
	 * 统一输出内容
	 * @param response 响应
	 * @param value 结果
	 * @throws IOException 异常
	 */
	public static void write(HttpServletResponse response, String value) throws IOException {
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer = response.getWriter();
		writer.println(value);
	}

	public static void text(String fileName, byte[] bytes, HttpServletResponse response) throws IOException {
		download(response, fileName + FileExtEnum.FILE_EXT_TXT.getName(), bytes, ContentTypeEnum.APPLICATION_TEXT);
	}

	public static void json(String fileName, byte[] bytes, HttpServletResponse response) throws IOException {
		download(response, fileName + FileExtEnum.FILE_EXT_JSON.getName(), bytes, ContentTypeEnum.APPLICATION_JSON);
	}

	public static void csv(String fileName, byte[] bytes, HttpServletResponse response) throws IOException {
		download(response, fileName + FileExtEnum.FILE_EXT_CSV.getName(), bytes, ContentTypeEnum.APPLICATION_CSV);
	}

	public static void xls(String fileName, byte[] bytes, HttpServletResponse response) throws IOException {
		download(response, fileName + FileExtEnum.FILE_EXT_XLS.getName(), bytes, ContentTypeEnum.APPLICATION_EXCEL);
	}

	public static void xlsx(String fileName, byte[] bytes, HttpServletResponse response) throws IOException {
		download(response, fileName + FileExtEnum.FILE_EXT_XLSX.getName(), bytes, ContentTypeEnum.APPLICATION_EXCEL);
	}

	/**
	 * 数据二进制下载
	 * @param fileName 文件名称 携带后缀
	 * @param bytes 二进制数组
	 * @param response 响应
	 * @throws IOException 异常
	 */
	public static void stream(String fileName, byte[] bytes, HttpServletResponse response) throws IOException {
		download(response, fileName, bytes, ContentTypeEnum.APPLICATION_STREAM);
	}

	/**
	 * 统一包装的文件下载
	 * @param response HttpServletResponse
	 * @param fileName 文件名称 携带文件后缀
	 * @param bytes 字节数组
	 * @param contentTypeEnum ContentType枚举
	 * @throws IOException 异常
	 */
	public static void download(HttpServletResponse response, String fileName, byte[] bytes,
			ContentTypeEnum contentTypeEnum) throws IOException {
		download(response, fileName, bytes, contentTypeEnum, CharsetKit.UTF_8);
	}

	/**
	 * 统一包装的文件下载
	 * @param response HttpServletResponse
	 * @param fileName 文件名称 携带文件后缀
	 * @param bytes 字节数组
	 * @param contentTypeEnum ContentType枚举
	 * @param charset 字符编码
	 * @throws IOException 异常
	 */
	public static void download(HttpServletResponse response, String fileName, byte[] bytes,
			ContentTypeEnum contentTypeEnum, String charset) throws IOException {
		response.addHeader("Content-Length", "" + bytes.length);
		response.setContentType(contentTypeEnum + ";charset=" + charset);
		OutputStream os = response.getOutputStream();
		ResponseUtil.setAttachmentResponseHeader(response, fileName);
		os.write(bytes);
		os.flush();
		os.close();
	}

	/**
	 * 下载文件名重新编码
	 * @param response 响应对象
	 * @param realFileName 真实文件名
	 */
	public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) {
		String fileName = percentEncode(realFileName);
		response.setHeader(HeaderEnum.HEADER_CONTENT_DISPOSITION.getName(),
				String.format("attachment; filename=%s", fileName));
		response.setHeader(HeaderEnum.HEADER_DOWNLOAD_FILENAME.getName(), fileName);
	}

	private static String percentEncode(String fileName) {
		try {
			fileName = URLEncoder.encode(fileName, CharsetKit.UTF_8);
			fileName = fileName.replace("+", "%20");
			return fileName;
		}
		catch (UnsupportedEncodingException e) {
			return fileName;
		}
	}

}
